package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"time"

	"github.com/xuri/excelize/v2"
)

const (
	excelFile    = "./contract.xlsx"
	sheetName    = "Sheet1"
	decryptAPI   = "http://comm.taocheche.com/api/v1/batchdecrypt"
	maxBatchSize = 2
	requestDelay = 1 * time.Second
)

var (
	token string
)

// 修改请求结构体
type DecryptRequest struct {
	Token string   `json:"token"`  // 新增token字段
	Data  []string `json:"data"`
}

type DecryptResponse struct {
	Result  map[string]string `json:"result"`
	RetCode int               `json:"retCode"`
	RetMsg  string            `json:"retMsg"`
}

func init() {
	flag.StringVar(&token, "token", "", "API认证令牌(必须)")
}

func main() {
	flag.Parse()

	if token == "" {
		fmt.Println("错误：必须通过 -token 参数提供认证令牌")
		flag.Usage()
		os.Exit(1)
	}
	f, err := excelize.OpenFile(excelFile)
	if err != nil {
		panic(fmt.Sprintf("打开文件失败: %v", err))
	}
	defer f.Close()

	rows, err := f.GetRows(sheetName)
	if err != nil {
		panic(fmt.Sprintf("读取Sheet失败: %v", err))
	}

	var dataRecords []struct {
		RowIndex int
		Col5     string
		Col6     string
	}

	for rowIndex, row := range rows {
		if len(row) >= 6 {
			dataRecords = append(dataRecords, struct {
				RowIndex int
				Col5     string
				Col6     string
			}{
				RowIndex: rowIndex + 1,
				Col5:     row[4],
				Col6:     row[5],
			})
		}
	}

	for i := 0; i < len(dataRecords); i += maxBatchSize {
		end := i + maxBatchSize
		if end > len(dataRecords) {
			end = len(dataRecords)
		}
		batch := dataRecords[i:end]

		var requestData []string
		for _, record := range batch {
			requestData = append(requestData, record.Col5, record.Col6)
		}

		// 发送解密请求（修改调用方式）
		decryptedData, err := batchDecrypt(requestData, token)
		if err != nil {
			fmt.Printf("解密失败: %v\n", err)
			continue
		}

		for _, record := range batch {
			col5Decrypted := decryptedData[record.Col5]
			col6Decrypted := decryptedData[record.Col6]

			f.SetCellValue(sheetName, fmt.Sprintf("G%d", record.RowIndex), col5Decrypted)
			f.SetCellValue(sheetName, fmt.Sprintf("H%d", record.RowIndex), col6Decrypted)
		}

		time.Sleep(requestDelay)
	}

	if err := f.Save(); err != nil {
		panic(fmt.Sprintf("保存文件失败: %v", err))
	}
	fmt.Println("处理完成，文件已保存")
}

// 修改后的解密函数
func batchDecrypt(data []string, token string) (map[string]string, error) {
	// 构造带token参数的URL
	apiURL, err := url.Parse(decryptAPI)
	if err != nil {
		return nil, fmt.Errorf("解析API地址失败: %w", err)
	}
	
	// 添加token查询参数
	query := apiURL.Query()
	query.Add("token", token)
	apiURL.RawQuery = query.Encode()

	// 记录请求日志
	fmt.Printf("\n======= 请求信息 =======\n")
	fmt.Printf("完整URL: %s\n", apiURL.String())
	fmt.Printf("请求体: %s\n", formatJSONBody(data))
	fmt.Printf("=======================\n")

	// 序列化请求体
	requestBody, err := json.Marshal(data)
	if err != nil {
		return nil, fmt.Errorf("序列化请求体失败: %w", err)
	}

	// 创建HTTP请求
	req, err := http.NewRequest("POST", apiURL.String(), bytes.NewBuffer(requestBody))
	if err != nil {
		return nil, fmt.Errorf("创建请求失败: %w", err)
	}
	req.Header.Set("Content-Type", "application/json")

	// 发送请求
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("API请求失败: %w", err)
	}
	defer resp.Body.Close()

	// 记录响应日志
	fmt.Printf("\n======= 响应信息 =======\n")
	fmt.Printf("状态码: %d\n", resp.StatusCode)
	body, _ := ioutil.ReadAll(resp.Body)
	fmt.Printf("原始响应: %s\n", string(body))
	fmt.Printf("=======================\n")

	// 解析响应
	var response DecryptResponse
	if err := json.Unmarshal(body, &response); err != nil {
		return nil, fmt.Errorf("解析响应失败: %w", err)
	}

	if response.RetCode != 200 {
		return nil, fmt.Errorf("业务错误: %s (代码%d)", response.RetMsg, response.RetCode)
	}

	return response.Result, nil
}

// 格式化JSON请求体
func formatJSONBody(data []string) string {
	buf := &bytes.Buffer{}
	encoder := json.NewEncoder(buf)
	encoder.SetIndent("", "  ")
	if err := encoder.Encode(data); err != nil {
		return fmt.Sprintf("[序列化错误: %v]", err)
	}
	return buf.String()
}